package pl.umk.mat.fred.unicore.urc.storagemanagement.tools;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.eclipse.jface.preference.IPreferenceStore;
import org.unigrids.services.atomic.types.ProtocolType;

import pl.umk.mat.fred.unicore.urc.storagemanagement.StorageManagementActivator;
import pl.umk.mat.fred.unicore.urc.storagemanagement.preferences.PreferenceConstants;
import pl.umk.mat.fred.unicore.urc.storagemanagement.tree.nodes.CatalogNode;
import pl.umk.mat.fred.unicore.urc.storagemanagement.tree.nodes.GridNode;
import pl.umk.mat.fred.unicore.urc.storagemanagement.tree.nodes.MultiplyCatalogNode;
import pl.umk.mat.fred.unicore.urc.storagemanagement.tree.nodes.Node;
import pl.umk.mat.fred.unicore.urc.storagemanagement.tree.nodes.StorageNode;
import pl.umk.mat.fred.unicore.urc.storagemanagement.unicore.Storage;

import de.fzj.unicore.rcp.common.Constants;
import de.fzj.unicore.rcp.common.UnicoreCommonActivator;
import de.fzj.unicore.rcp.common.utils.UnicoreStorageTools;
import de.fzj.unicore.uas.fts.uftp.UFTPConstants;

public class StorageTools {
	
	public static ProtocolType.Enum getProtocol(long fileSize, ProtocolType.Enum[] supportedProtocols) {
		ProtocolType.Enum[] protocols = UnicoreStorageTools.getPreferredProtocolOrder(fileSize);
		List<ProtocolType.Enum> supportedProtocolList = Arrays.asList(supportedProtocols);
		for (ProtocolType.Enum p : protocols) {
			if (supportedProtocolList.contains(p)) {
				return p;
			}
		}
		return ProtocolType.BFT;
	}
	
	public static ProtocolType.Enum getProtocol(long fileSize, ProtocolType.Enum[] supportedProtocols, ProtocolType.Enum[] supportedProtocols2) {
		ProtocolType.Enum[] protocols = UnicoreStorageTools.getPreferredProtocolOrder(fileSize);
		List<ProtocolType.Enum> supportedProtocolList = Arrays.asList(supportedProtocols);
		List<ProtocolType.Enum> supportedProtocolList2 = Arrays.asList(supportedProtocols2);
		for (ProtocolType.Enum p : protocols) {
			if (supportedProtocolList.contains(p) && supportedProtocolList2.contains(p)) {
				return p;
			}
		}
		return ProtocolType.BFT;
	}
	
	public static void provideParameters(Map<String, String> params, String protocol) {
		if (ProtocolType.UFTP.toString().equals(protocol)) {

			// setting uftp.streams
			Integer uftpStreams = UnicoreCommonActivator.getDefault()
			.getPreferenceStore().getInt(Constants.P_UFTP_STREAM_NUMBER);
			params.put(UFTPConstants.PARAM_STREAMS, uftpStreams.toString());

			// setting uftp.client.host
			String uftpClientHost = UnicoreCommonActivator.getDefault()
			.getPreferenceStore()
			.getDefaultString(Constants.P_UFTP_CLIENT_HOST);

			String uftpUserClientHost = UnicoreCommonActivator.getDefault()
			.getPreferenceStore().getString(Constants.P_UFTP_CLIENT_HOST);
			if (!uftpUserClientHost.equals(""))
			{
				uftpClientHost = uftpUserClientHost;
			}
			params.put(UFTPConstants.PARAM_CLIENT_HOST, uftpClientHost);
			//add unique secret
			if(params.get(UFTPConstants.PARAM_SECRET)==null){
				params.put(UFTPConstants.PARAM_SECRET, UUID.randomUUID().toString());
			}
		}
	}
	
	public static Storage randomStorage(GridNode gn) {
		return randomStorageNode(gn).getStorage();
	}
	
	public static StorageNode randomStorageNode(GridNode gn) {
		IPreferenceStore preferenceStore = StorageManagementActivator.getDefault().getPreferenceStore();
		Random random = new Random();
		List<StorageNode> storages = new ArrayList<StorageNode>(gn.getChildren().size());
		List<Integer> values = new ArrayList<Integer>(gn.getChildren().size());
		int sum = 0;
		for (Node n : gn.getChildren()) {
			StorageNode sn = (StorageNode) n;
			int val = preferenceStore.getInt(PreferenceConstants.P_PRIORITY_PREFIX + sn.getStorage().getUrl());
			if (val == 0) {
				continue;
			}
			storages.add(sn);
			sum += val;
			values.add(sum);
		}
		
		int r = random.nextInt(sum);
		int i = 0;
		for (int v : values) {
			if (r < v) {
				return storages.get(i);
			}
			i++;
		}
		return null;
	}
	
	public static CatalogNode randomCatalogNode(MultiplyCatalogNode mc) {
		IPreferenceStore preferenceStore = StorageManagementActivator.getDefault().getPreferenceStore();
		Random random = new Random();
		List<CatalogNode> catalogs = new ArrayList<CatalogNode>(mc.getCatalogs().size());
		List<Integer> values = new ArrayList<Integer>(mc.getCatalogs().size());
		int sum = 0;
		for (CatalogNode cn : mc.getCatalogs()) {
			StorageNode sn = cn.getStorageNode();
			int val = preferenceStore.getInt(PreferenceConstants.P_PRIORITY_PREFIX + sn.getStorage().getUrl());
			if (val == 0) {
				continue;
			}
			catalogs.add(cn);
			sum += val;
			values.add(sum);
		}
		
		int r = random.nextInt(sum);
		int i = 0;
		for (int v : values) {
			if (r < v) {
				return catalogs.get(i);
			}
			i++;
		}
		return null;
	}

}
